package com.fengwk.resource.service.impl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fengwk.resource.dao.ResFileDao;
import com.fengwk.resource.face.entity.ResFile;
import com.fengwk.resource.service.DownloadService;
import com.fengwk.support.exception.BaseException;
import com.fengwk.support.util.CodeUtils;
import com.fengwk.support.util.CollectionUtils;
import com.fengwk.support.util.CompressUtils;
import com.fengwk.support.util.DownloadUtils;
import com.fengwk.support.util.FileExtensionUtils;
import com.fengwk.support.util.IoUtils;
import com.fengwk.support.util.StringUtils;

@Service
public class DownloadServiceImpl implements  DownloadService {

	@Autowired
	private HttpServletRequest request;
	@Autowired
	private HttpServletResponse response;
	
	@Autowired
	private ResFileDao rfDao;
	
	@Override
	public void single(Long fileId, String fileName) {
		if(fileId == null) {
			return;
		}
		List<ResFile> files = new ArrayList<ResFile>();
		files.add(rfDao.findByFileId(fileId));
		downLoad(response, fileName, files, false);
	}

	@Override
	public void packages(Collection<Long> fileIds, String fileName) {
		if(CollectionUtils.isBlank(fileIds)) {
			return;
		}
		List<ResFile> files = rfDao.queryInFileIds(fileIds);
		if (CollectionUtils.isBlank(files)) {
			throw new BaseException("文件不存在");
		}
		downLoad(response, fileName, files, true);
	}
	
	private void downLoad(HttpServletResponse response, String fileName, List<ResFile> files, boolean zip) {
		// 压缩
		StringBuffer fileIdsSb = new StringBuffer();
		// 获取文件bytes
		byte[] bytes = null;
		if (!zip && files.size() == 1) {
			String absolutePath = files.get(0).getAbsolutePath();
			assertAbsolutePath(absolutePath);
			InputStream is = IoUtils.buildInputStream(absolutePath);
			if (is == null) {
				throw new BaseException("未找到相应文件");
			}
			bytes = IoUtils.toBytes(is, true);
		} else {
			bytes = zipFiles(files, fileIdsSb);
		}
		if (bytes == null) {
			throw new BaseException("文件获取失败");
		}
		// 处理下载
		String _fileName = StringUtils.isBlank(fileName) ? (files.size() == 1 ? files.get(0).getName() : CodeUtils.uuid()) : fileName;
		if(zip) {
			String[] fileNameSplit = FileExtensionUtils.split(_fileName);
			if(fileNameSplit != null) {
				_fileName = fileNameSplit[0] + ".zip";
			} else {
				_fileName += ".zip";
			}
		}
		DownloadUtils.download(request, response, _fileName, (long) bytes.length, IoUtils.toInputStream(bytes));
	}
	
	/**
	 * 压缩文件
	 */
	public byte[] zipFiles(List<ResFile> files, StringBuffer fileIdsSb) {
		Map<String, InputStream> srcInMap = new HashMap<String, InputStream>();
		List<String> fileNameCache = new ArrayList<String>();
		for(ResFile file: files) {
			String absolutePath = file.getAbsolutePath();
			assertAbsolutePath(absolutePath);
			InputStream in = null;
			try {
				in = new FileInputStream(absolutePath);
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
			String filename = filename(file);
			if(CollectionUtils.isNotBlank(fileNameCache)) {
				for(String s: fileNameCache) {
					if(filename.equals(s)) {
						String[] fileNameSplit = FileExtensionUtils.split(filename);
						if(fileNameSplit == null) {
							filename = CodeUtils.uuid();
						} else if (fileNameSplit.length == 2) {
							filename = fileNameSplit[0] + "_" + CodeUtils.uuid() + "." + fileNameSplit[1];
						} else if (fileNameSplit.length == 1) {
							filename = fileNameSplit[0] + "_" + CodeUtils.uuid();
						}
					}
				}
			}
			srcInMap.put(filename, in);
			fileNameCache.add(filename);
			fileIdsSb.append(file.getFileId() + ",");
		}
		byte[] bytes = CompressUtils.zip(srcInMap);
		if(bytes == null || bytes.length <= 0) 
			return null;
		return bytes;
	}
	
	// 获取文件名
	private String filename(ResFile file) {
		String fileName = file.getName();
		if(StringUtils.isBlank(fileName)) {
			fileName = file.getFileId() + "";
		}
		return fileName;
	}
	
	private void assertAbsolutePath(String absolutePath) {
		if(StringUtils.isBlank(absolutePath))
			throw new BaseException("该文件不支持下载");
	}
	
}
